﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rappelz.GameServer
{
    public class SkillBase
    {
        public enum TargetType : short
        {
            Misc = 0,
            Target = 1,
            RegionWithTarget = 2,
            RegionWithoutTarget = 3,
            Region = 4,
            TargetExceptCaster = 6,
            Party = 21,
            Guild = 22,
            AttackTeam = 23,
            Summon = 31,
            PartySummon = 32,
            RegionNearMainSummonWithoutTaget = 44,
            SelfWithSummon = 45,
            PartyWithSummon = 51,
            Master = 101,
            SelfWithMaster = 102,
            CreatureTypeNone = 201,
            CreatureTypeFire = 202,
            CreatureTypeWater = 203,
            CreatureTypeWind = 204,
            CreatureTypeEarth = 205,
            CreatureTypeLight = 206,
            CreatureTypeDark = 207,
        }

        public enum SkillId : int
        {
            AdvWeaponExpert = 1022,
            LifeOfDarkness = 1033,
            IncreaseEnergy = 1082,
            DualSwordExpert = 1181,
            ArmorMastery = 1201,
            CreatureControl = 1801,
            CreatureMastery = 1811,
            TechnicalCreatureControl = 1881,
            GaiaArmorMastery = 0x4B2,
            RaiseExp = 0x2AFA,
            RaiseJP = 0x2AFB,
            GaiaForceSaving = 0xA47,
            ItemResurrectionScroll = 0x1771,
            ItemRegenerationScroll = 0x1772,
            ItemHealingScroll = 0x1773,
            ItemManaRecoveryScroll = 0x1774,
            ItemAntidoteScroll = 0x1775,
            ItemRechargeScroll = 0x1776,
            TownPortal = 0x1777,
            Return = 0xEDA,
            ForceChip = 0x1778,
            SoulChip = 0x1779,
            LunaChip = 0x177A,
            ItemPerfectCreatureResurrectionScroll = 0x177D,
            ItemPieceOfStrength = 0x177E,
            ItemPieceOfVitality = 0x177F,
            ItemPieceOfDexterity = 0x1780,
            ItemPieceOfAgility = 0x1781,
            ItemPieceOfIntelligence = 0x1782,
            ItemPieceOfMentality = 0x1783,
            ReturnFeather = 0x1784,
            ReturnBackFeather = 0x1785,
            FireBombPhysical = -727,
            FireBombMagical = -726,
//             0x1786,SKILL_ITEM_REGENERATION_SCROLL_LV1
//             0x1787,SKILL_ITEM_REGENERATION_SCROLL_LV2
//             0x1788,SKILL_ITEM_REGENERATION_SCROLL_LV3
//             0x1789,SKILL_ITEM_REGENERATION_SCROLL_LV4
//             0x178A,SKILL_ITEM_REGENERATION_SCROLL_LV5
//             0x178B,SKILL_ITEM_REGENERATION_SCROLL_LV6
//             0x178C,SKILL_ITEM_REGENERATION_SCROLL_LV7
//             0x178D,SKILL_ITEM_REGENERATION_SCROLL_LV8
//             0x178E,SKILL_ITEM_HEALING_SCROLL_LV1
//             0x178F,SKILL_ITEM_HEALING_SCROLL_LV2
//             0x1790,SKILL_ITEM_HEALING_SCROLL_LV3
//             0x1791,SKILL_ITEM_HEALING_SCROLL_LV4
//             0x1792,SKILL_ITEM_HEALING_SCROLL_LV5
//             0x1793,SKILL_ITEM_HEALING_SCROLL_LV6
//             0x1794,SKILL_ITEM_HEALING_SCROLL_LV7
//             0x1795,SKILL_ITEM_HEALING_SCROLL_LV8
//             0x1796,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV1
//             0x1797,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV2
//             0x1798,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV3
//             0x1799,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV4
//             0x179A,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV5
//             0x179B,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV6
//             0x179C,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV7
//             0x179D,SKILL_ITEM_MANA_RECOVERY_SCROLL_LV8
//             0x179E,SKILL_CALL_BLACK_PINE_TEA
//             0x179F,SKILL_ITEM_SUMMON_SPEED_UP_SCROLL_LV1
//             0x17A0,SKILL_ITEM_SUMMON_SPEED_UP_SCROLL_LV2
//             0x17A1,SKILL_ITEM_SUMMON_SPEED_UP_SCROLL_LV3
//             0x17AD,SKILL_ITEM_ALTERED_PIECE_OF_STRENGTH
//             0x17AE,SKILL_ITEM_ALTERED_PIECE_OF_VITALITY
//             0x17AF,SKILL_ITEM_ALTERED_PIECE_OF_DEXTERITY
//             0x17B0,SKILL_ITEM_ALTERED_PIECE_OF_AGILITY
//             0x17B1,SKILL_ITEM_ALTERED_PIECE_OF_INTELLIGENCE
//             0x17B2,SKILL_ITEM_ALTERED_PIECE_OF_MENTALITY
//             0x17B3,SKILL_ITEM_ALTERED_PIECE_OF_STRENGTH_QUEST
//             0x17B4,SKILL_ITEM_ALTERED_PIECE_OF_VITALITY_QUEST
//             0x17B5,SKILL_ITEM_ALTERED_PIECE_OF_DEXTERITY_QUEST
//             0x17B6,SKILL_ITEM_ALTERED_PIECE_OF_AGILITY_QUEST
//             0x17B7,SKILL_ITEM_ALTERED_PIECE_OF_INTELLIGENCE_QUEST
//             0x17B8,SKILL_ITEM_ALTERED_PIECE_OF_MENTALITY_QUEST
//             0x1AF5,SKILL_COLLECTING
//             0x1AF6,SKILL_MINING
//             0x1AF7,SKILL_OPERATING
//             0x1AF8,SKILL_ACTIVATING
//             0x1AF9,SKILL_OPERATE_DEVICE
//             0x1AFA,SKILL_OPERATE_DUNGEON_CORE
//             0x1AFD,SKILL_OPERATE_EXPLORATION
//             0xFFFFFD26,SKILL_TREE_OF_HEALING_TYPE_A
//             0xFFFFFD27,SKILL_TREE_OF_HEALING_TYPE_B
            Shoveling = 6907,
            PetTaming = 6908,
            CreatureTaming = 4003,
//             0x2719,SKILL_THROW_SMALL_SNOWBALL
//             0x271A,SKILL_THROW_BIG_SNOWBALL
//             0x2AF9,SKILL_CREATURE_RIDING
//             0x2EE1,SKILL_UNIT_EXPERT_LV2
//             0x2EE2,SKILL_UNIT_EXPERT_LV3
//             0x2EE3,SKILL_UNIT_EXPERT_LV4
//             0x2EE4,SKILL_UNIT_EXPERT_LV5
//             0x2EE5,SKILL_UNIT_EXPERT_LV6
//             0x36B1,SKILL_AMORY_UNIT
            TwinBladeExpert = 61010,
//             0xFFFFEE52,SKILL_TWIN_BLADE_EXPERT
            TwinAxeExpert = 61015,
//             0xFFFFFD28,SKILL_NEW_YEAR_CHAMPAGNE
//             0xFFFFFD2D,SKILL_NAMUIR_LEAF_POISON
//             0xFFFFFD2E,SKILL_NAMUIR_RIND_BLEEDING
        }

        public enum EffectType : int 
        {
            Misc = 0,
            Unk1 = 1,
            RespawnMonsterNear = 2,
            SummonScroll = 6,
            PhysicalSingleDamageT1 = 101,
            PhysicalMultipleDamageT1 = 102,
            PhysicalSingleDamageT2 = 103,
            PhysicalMultipleDamageT2 = 104,
            PhysicalDirectionDamage = 105,
            PhysicalSingleDamageT3 = 106,
            PhysicalMultipleDamageT3 = 107,
            PhysicalMultipleDamageTripleAttackOld = 108,
            PhysicalSingleRegionDamageOld = 111,
            PhysicalMultipleRegionDamageOld = 112,
            PhysicalSingleSpecialRegionDamageOld = 113,
            PhysicalSingleDamageWithShield = 117,
            PhysicalAbsorbDamage = 121,
            PhysicalMultipleSpecialRegionDamageOld = 122,
            PhysicalSingleDamageAddEnergyOld = 125,
            PhysicalSingleDamageKnockbackOld = 131,
            PhysicalSingleRegionDamageKnockbackOld = 132,
            PhysicalSingleDamageWithoutWeapnRushKnockBack = 151,
            PhysicalSingleDamageRushKnockBackOld = 152,
            MagicSingleDamageT1Old = 201,
            MagicMultipleDamageT1Old = 202,
            MagicSingleDamageT2Old = 203,
            MagicMultipleDamageT2Old = 204,
            MagicMultipleDamageT3Old = 205,
            MagicMultipleDamageT1DealSummonHpOld = 206,
            MagicSingleRegionDamageOld = 211,
            MagicMultipleRegionDamageOld = 212,
            MagicSpecialRegionDamageOld = 213,
            MagicMultipleRegionDamageT2Old = 214,
            MagicAbsorbDamageOld = 221,
            MagicSingleDamage = 231,
            MagicMultipleDamage = 232,
            MagicMultipleDamageDealSummonHp = 233,
            MagicSingleDamageOrDeath = 234,
            MagicDamageWithAbsorbHPMP = 235,
            MagicSinglePercentDamage = 236,
            MagicSinglePercentManaburn = 237,
            MagicSingelPercentOfMaxMPManaburn = 238,
            MagicSingleDamageAddRandomState = 239,
            MagicalSingleDamageByConsumingTargetsState = 240,
            MagicMultipleDamageAtOnce = 241,
            MagicSingleRegionDamage = 261,
            MagicSpecialRegionDamage = 262,
            MagicMultipleRegionDamage = 263,
            MagicRegionPercentDamage = 264,
            MagicSingleRegionDamageUsingCorpse = 265,
            AddHPMPAbsorbHPMP = 266,
            MagicSingleRegionDamageBySummonDead = 267,
            MagicSingleRegionDamageAddRandomState = 268,
            MagicMultipleRegionDamageAtOnce = 269,
            AreaEffectMagicDamage = 271,
            AreaEffectMagicDamageAndHeal = 272,
            AreaEffectMagicDamageAndHealT2 = 273,
            AddState = 301,
            AddRegionState = 302,
            CastingCancelWithAddState = 304,
            AddStateBySelfCost = 305,
            AddRegionStateBySelfCost = 306,
            AddStateByTargetType = 307,
// Data           :     constant 0x134, Constant, Type: int, EF_ADD_STATES_WITH_EACH_DIFF_LV
// Data           :     constant 0x135, Constant, Type: int, EF_ADD_STATES_WITH_EACH_DIFF_LV_DURATION
            AddStateByItemCost = 314,
// Data           :     constant 0x160, Constant, Type: int, EF_AREA_EFFECT_MAGIC_DAMAGE_OLD
// Data           :     constant 0x161, Constant, Type: int, EF_AREA_EFFECT_HEAL
// Data           :     constant 0x17D, Constant, Type: int, EF_TRAP_PHYSICAL_DAMAGE
// Data           :     constant 0x17E, Constant, Type: int, EF_TRAP_MAGICAL_DAMAGE
// Data           :     constant 0x17F, Constant, Type: int, EF_TRAP_MULTIPLE_PHYSICAL_DAMAGE
// Data           :     constant 0x180, Constant, Type: int, EF_TRAP_MULTIPLE_MAGICAL_DAMAGE
// Data           :     constant 0x191, Constant, Type: int, EF_REMOVE_BAD_STATE
// Data           :     constant 0x192, Constant, Type: int, EF_REMOVE_GOOD_STATE
// Data           :     constant 0x1F5, Constant, Type: int, EF_ADD_HP
// Data           :     constant 0x1F6, Constant, Type: int, EF_ADD_MP
// Data           :     constant 0x1F8, Constant, Type: int, EF_RESURRECTION
// Data           :     constant 0x1F9, Constant, Type: int, EF_ADD_HP_MP
            AddHpMpBySummonDamage = 506,// Data           :     constant 0x1FA, Constant, Type: int, EF_ADD_HP_MP_BY_SUMMON_DAMAGE
            AddHpMpBySummonDead = 507,
// Data           :     constant 0x1FC, Constant, Type: int, EF_ADD_REGION_HP_MP
// Data           :     constant 0x1FD, Constant, Type: int, EF_ADD_HP_BY_ITEM
// Data           :     constant 0x1FE, Constant, Type: int, EF_ADD_MP_BY_ITEM
// Data           :     constant 0x1FF, Constant, Type: int, EF_CORPSE_ABSORB
            AddHpMpByStealSummonHpMp = 512,
// Data           :     constant 0x201, Constant, Type: int, EF_ADD_HP_MP_WITH_LIMIT_PERCENT
// Data           :     constant 0x209, Constant, Type: int, EF_ADD_REGION_HP
// Data           :     constant 0x20A, Constant, Type: int, EF_ADD_REGION_MP
            Summon = 601,
            Unsummon = 602,
            UnsummonAndAddState = 605,
            ToggleAura = 701,
            ToggleDifferentialAura = 702,
// Data           :     constant 0x384, Constant, Type: int, EF_TAUNT
            RegionTaunt = 901,
            RemoveHate = 902,
            RegionRemoveHate = 903,
// Data           :     constant 0x3E9, Constant, Type: int, EF_CORPSE_EXPLOSION
// Data           :     constant 0x2329, Constant, Type: int, EF_CREATE_ITEM
            ActivateFieldProp = 9501,
            RegionHealByFieldProp = 9502,
            AreaAffectHealByHieldProp = 9503,
            WeaponMastery = 10001,
// Data           :     constant 0x2712, Constant, Type: int, EF_BATTLE_PARAMTER_INCREASE
// Data           :     constant 0x2713, Constant, Type: int, EF_BLOCK_INCREASE
// Data           :     constant 0x2714, Constant, Type: int, EF_ATTACK_RANGE_INCREASE
// Data           :     constant 0x2715, Constant, Type: int, EF_RESISTANCE_INCREASE
// Data           :     constant 0x2716, Constant, Type: int, EF_MAGIC_REGISTANCE_INCREASE
// Data           :     constant 0x2717, Constant, Type: int, EF_SPECIALIZE_ARMOR
            IncreaseBaseAttribute = 10008,
// Data           :     constant 0x2719, Constant, Type: int, EF_INCREASE_EXTENSION_ATTRIBUTE
// Data           :     constant 0x271A, Constant, Type: int, EF_SPECIALIZE_ARMOR_AMP
// Data           :     constant 0x271B, Constant, Type: int, EF_AMPLIFY_BASE_ATTRIBUTE
// Data           :     constant 0x271C, Constant, Type: int, EF_MAGIC_TRAINING
// Data           :     constant 0x271D, Constant, Type: int, EF_HUNTING_TRAINING
// Data           :     constant 0x271E, Constant, Type: int, EF_BOW_TRAINING
// Data           :     constant 0x271F, Constant, Type: int, EF_INCREASE_STAT
// Data           :     constant 0x2720, Constant, Type: int, EF_AMPLIFY_STAT

            IncreaseHPMP = 10021,
// Data           :     constant 0x2726, Constant, Type: int, EF_AMPLIFY_HP_MP
// Data           :     constant 0x2727, Constant, Type: int, EF_HEALING_AMPLIFY
// Data           :     constant 0x2728, Constant, Type: int, EF_HEALING_AMPLIFY_BY_ITEM
// Data           :     constant 0x2729, Constant, Type: int, EF_HEALING_AMPLIFY_BY_REST
// Data           :     constant 0x272A, Constant, Type: int, EF_HATE_AMPLIFY
            IncreaseSummonHPMPSP = 10031,
            AmplifySummonHPMPSP = 10032,
            CreatureAssignmentIncrease = 10033,
// Data           :     constant 0x2732, Constant, Type: int, EF_CREATURE_ACQUIREMENT_INCREASE
// Data           :     constant 0x2733, Constant, Type: int, EF_BELT_ON_PARAMETER_INC
// Data           :     constant 0x2734, Constant, Type: int, EF_BELT_ON_ATTRIBUTE_INC
// Data           :     constant 0x2735, Constant, Type: int, EF_BELT_ON_ATTRIBUTE_EX_INC
// Data           :     constant 0x2736, Constant, Type: int, EF_BELT_ON_ATTRIBUTE_HPMP_INC
// Data           :     constant 0x2739, Constant, Type: int, EF_UNIT_EXPERT
// Data           :     constant 0x273A, Constant, Type: int, EF_BELT_ON_PARAMETER_AMP
// Data           :     constant 0x273B, Constant, Type: int, EF_BELT_ON_ATTRIBUTE_AMP
// Data           :     constant 0x273C, Constant, Type: int, EF_BELT_ON_ATTRIBUTE_EX_AMP
// Data           :     constant 0x273D, Constant, Type: int, EF_BELT_ON_ATTRIBUTE_HPMP_AMP
// Data           :     constant 0x273E, Constant, Type: int, EF_SUMMON_ITEM_EXPERT
// Data           :     constant 0x7531, Constant, Type: int, EF_PHYSICAL_SINGLE_DAMAGE
// Data           :     constant 0x7532, Constant, Type: int, EF_PHYSICAL_SINGLE_DAMAGE_ABSORB
// Data           :     constant 0x7533, Constant, Type: int, EF_PHYSICAL_SINGLE_DAMAGE_ADD_ENERGY
            PhysicalSingleDamageRush = 30004,
            PhysicalSingleDamageRushKnockback = 30005,
// Data           :     constant 0x7536, Constant, Type: int, EF_PHYSICAL_SINGLE_DAMAGE_KNOCKBACK
// Data           :     constant 0x7537, Constant, Type: int, EF_PHYSICAL_SINGLE_REGION_DAMAGE_KNOCKBACK
// Data           :     constant 0x7538, Constant, Type: int, EF_PHYSICAL_SINGLE_REGION_DAMAGE_KNOCKBACK_SELF
// Data           :     constant 0x7539, Constant, Type: int, EF_PHYSICAL_REALTIME_MULTIPLE_DAMAGE
// Data           :     constant 0x753A, Constant, Type: int, EF_PHYSICAL_MULTIPLE_DAMAGE_TRIPLE_ATTACK
// Data           :     constant 0x753B, Constant, Type: int, EF_PHYSICAL_SINGLE_REGION_DAMAGE
// Data           :     constant 0x753C, Constant, Type: int, EF_PHYSICAL_MULTIPLE_REGION_DAMAGE
// Data           :     constant 0x753D, Constant, Type: int, EF_PHYSICAL_SINGLE_SPECIAL_REGION_DAMAGE
// Data           :     constant 0x753E, Constant, Type: int, EF_PHYSICAL_MULTIPLE_SPECIAL_REGION_DAMAGE
// Data           :     constant 0x753F, Constant, Type: int, EF_PHYSICAL_MULTIPLE_SPECIAL_REGION_DAMAGE_SELF
// Data           :     constant 0x7540, Constant, Type: int, EF_PHYSICAL_MULTIPLE_DAMAGE
// Data           :     constant 0x7541, Constant, Type: int, EF_PHYSICAL_REALTIME_MULTIPLE_DAMAGE_KNOCKBACK
// Data           :     constant 0x7542, Constant, Type: int, EF_PHYSICAL_REALTIME_MULTIPLE_REGION_DAMAGE
            PhysicalSingleDamageByConsumingTargetsState = 30019,
// Data           :     constant 0x754E, Constant, Type: int, EF_PHYSICAL_SINGLE_REGION_DAMAGE_WITH_CAST_CANCEL
// Data           :     constant 0x7725, Constant, Type: int, EF_RESURRECTION_WITH_RECOVER
            RemoveStateGroup = 30601,
// Data           :     constant 0x7919, Constant, Type: int, EF_WEAPON_TRAINING
// Data           :     constant 0x791A, Constant, Type: int, EF_AMPLIFY_BASE_ATTRIBUTE_OLD
// Data           :     constant 0x791B, Constant, Type: int, EF_AMPLIFY_EXT_ATTRIBUTE
            AmplifyExpForSummon = 32001,
    }

//         Enum           :   <unnamed-tag>, Type: int

// BaseClass      :   SkillBase, offset = 0x4
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Enum           :     <unnamed-tag>, Type: int
// Function       :     public int GetID()
// Function       :     public int GetNameID()
// Function       :     public bool IsValid()
// Function       :     public bool IsSystemSkill()
// Function       :     public bool IsPassive()
// Function       :     public bool IsPhysicalSkill()
// Function       :     public bool IsHarmful()
// Function       :     public bool IsNeedTarget()
// Function       :     public bool IsValidToCorpse()
// Function       :     public bool IsToggle()
// Function       :     public int GetCastRange()
// Function       :     public int GetValidRange()
// Function       :     public int GetCastCancelType()
// Function       :     public int GetCastCancelLevel()
// Function       :     public int GetToggleGroup()
// Function       :     public int GetSkillTargetType()
// Function       :     public int GetSkillEffectType()
// Function       :     public int GetElementalType()
// Function       :     public bool CheckEffectType(int)
// Function       :     public bool IsNeedShield()
// Function       :     public bool IsNeedWeapon()

        public bool IsUseableWeapon(ItemBase.ItemClass cl)
        {
            int c = (int)cl;

            if (c <= 210)
            {
                switch ( c )
                {
                    case 101:
                        return this.vf_one_hand_sword != 0;
                    case 102:
                        return this.vf_two_hand_sword != 0;
                    case 98:
                        return this.vf_double_dagger != 0;
                    case 96:
                        return this.vf_double_sword != 0;
                    case 103:
                        return this.vf_dagger != 0;
                    case 104:
                        return this.vf_spear != 0;
                    case 105:
                        return this.vf_axe != 0;
                    case 113:
                        return this.vf_one_hand_axe != 0;
                    case 95:
                        return this.vf_double_axe != 0;
                    case 106:
                        return this.vf_one_hand_mace != 0;
                    case 107:
                        return this.vf_two_hand_mace != 0;
                    case 109:
                        return this.vf_lightbow != 0;
                    case 108:
                        return this.vf_heavybow != 0;
                    case 110:
                        return this.vf_crossbow != 0;
                    case 111:
                        return this.vf_one_hand_staff != 0;
                    case 112:
                        return this.vf_two_hand_staff != 0;
                    case 210:
                        return this.vf_shield_only != 0;
                }
            }

            return false;
        }

// Function       :     public bool IsUseableOnAvatar()
// Function       :     public bool IsUseableOnMonster()
// Function       :     public bool IsUseableOnSummon()
// Function       :     public int GetCoolTimeGroupId()
// Function       :     public int GetStateType()
// Function       :     public int GetProbabilityOnHit(int)
// Function       :     public int GetStateId()

        public int GetStateLevel(int skill_lv, int enhance_lv)
        {
            return (int)(this.state_level_base
                 + (this.state_level_per_enhance * enhance_lv)
                 + (this.state_level_per_skl * skill_lv));
        }


        public int GetStateSecond(int skill_lv, int enhance_lv)
        {
            return (int)this.state_second + (int)enhance_lv * (int)this.state_second_per_enhance + skill_lv * (int)this.state_second_per_skl;
        }
// Function       :     public int GetCostEXP(int, int)
// Function       :     public int GetCostJP(int, int)
// Function       :     public int GetCostItemCode()
// Function       :     public const __int64 GetCostItemCount(int)
// Function       :     public int GetCostHP(int)
// Function       :     public float GetCostHPPercent(int)
// Function       :     public int GetCostMP(int, int)
// Function       :     public float GetCostMPPercent(int)
// Function       :     public int GetCostHavoc(int)

        public float GetCostEnergy(int skill_lv)
        {
            return (this.cost_energy_per_skl * skill_lv) + this.cost_energy;
        }
// Function       :     public int GetCostItem()
// Function       :     public int GetNeedLevel()
// Function       :     public int GetNeedHP()
// Function       :     public int GetNeedMP()
// Function       :     public int GetNeedHavoc()
// Function       :     public int GetNeedHavocBurst()
// Function       :     public float GetFireRange()

        public uint GetCoolTime(int enhance)
        {
            uint result;

            if (GameRule.bNoSkillCooltime)
                result = 0;
            else
                result = (uint)((this.delay_cooltime_mod_per_enhance * (float)enhance + 1.0f) * this.delay_cooltime);
            return result;
        }

// Function       :     public unsigned long GetCommonDelay()

        public uint GetCastDelay(int skill_lv, int enhance)
        {
            return (uint)( (float)((float)this.delay_cast + (float)skill_lv * (float)this.delay_cast_per_skl ) * (float)(this.delay_cast_mod_per_enhance * (float)enhance + 1.0f));
        }


        public int GetHitBonus(int enhance, int level_diff)
        {
            return this.hit_bonus + level_diff * this.percentage + enhance * this.hit_bonus_enhance;
        }
// Function       :     public class c_fixed<10000> GetVar(int)
// Function       :     public class c_fixed<10000> GetVar1()
// Function       :     public class c_fixed<10000> GetVar2()
// Function       :     public class c_fixed<10000> GetVar3()
// Function       :     public class c_fixed<10000> GetVar4()
// Function       :     public int GetHateMod()
// Function       :     public int GetCriticalBonus(int)
// Function       :     public int GetCastDelayByEnhance(int)
// Function       :     public int GetPowerByEnhance(int)
// Function       :     public int GetPowerOneByEnhance(int)
// Function       :     public int GetPowerDirectByEnhance(int)
// Function       :     public int GetMagicByEnhance(int)
// Function       :     public int GetMagicOneByEnhance(int)
// Function       :     public int GetMagicAreaByEnhance(int)
// Function       :     public int GetAbsorptionHPByEnhance(int)
// Function       :     public int GetAbsorptionMPByEnhance(int)
// Function       :     public int GetMagicAbsorptionHPByEnhance(int)
// Function       :     public int GetMagicAbsorptionMPByEnhance(int)
// Function       :     public int GetIncreaseByEnhance(int)
// Function       :     public int GetIncreaseOneByEnhance(int)
// Function       :     public int GetStateSuccessByEnhance(int)
// Function       :     public int GetStatePowerOneByEnhance(int)
// Function       :     public int GetStateMagicPowerByEnhance(int)
// Function       :     public int GetStatePowerByEnhance(int)
// Function       :     public int GetRecoveryByEnhance(int)
// Function       :     public int GetRecoveryPerByEnhance(int)
// Function       :     public int GetExpIncreaseByRevival(int)
// Function       :     public int GetAbsorptionHPPointByEnhance(int)
// Function       :     public int GetAbsorptionMPPointByEnhance(int)
// Function       :     public int GetTamingSuccessByEnhance(int)
// Function       :     public int GetCostMPPerSecondByEnhance(int)
// Function       :     public int GetNeedStateId()
// Function       :     public unsigned char GetNeedStateLevel()
// Function       :     public bool NeedStateExhaust()

        public int GetNeedJobPoint(int skill_lv)
        {
            int result;

            if (skill_lv <= 50)
                result = this.m_need_jp[skill_lv-1];
            else
                result = this.m_need_jp[49];
            return result;
        }

// Function       :     public void SkillBase::SetNeedJobPoint(int, int)
// Function       :     public char SkillBase::IsUsable(char)
        public byte IsUsable(byte nUseIndex)
        {
            byte res;

            switch ( nUseIndex )
            {
                case 0:
                    res = this.uf_self;
                    break;
                case 1:
                    res = this.uf_party;
                    break;
                case 2:
                    res = this.uf_guild;
                    break;
                case 3:
                    res = this.uf_neutral;
                    break;
                case 4:
                    res = this.uf_purple;
                    break;
                case 5:
                    res = this.uf_enemy;
                    break;
                default:
                    res = 0;
                    break;
            }
            return res;
        }

// Function       :     public int GetEffectType()
        public int GetHatePoint(int lv, int point, int enhance)
        {
            int result = 0;
            if (this.hate_mod != 0.0f)
            {
                if (this.hate_mod >= 0.0f)
                    result = (int)(point * this.hate_mod + this.hate_basic);
                else
                    result = (int)(this.hate_slv * lv + this.hate_basic + this.hate_enhance * enhance);
            }
            return result;
        }

        public int uid;                                         // 0x0, Member, Type: int, uid <1, 3, 0, 0, 4, 4, 0, 0, 0, 0>
        public int name_id;// Data           :     this+0x4, Member, Type: int, name_id <2, 3, 0, 0, 4, 8, 0, 0, 0, 0>
        public byte is_valid;// Data           :     this+0x8, Member, Type: char, is_valid <5, 10h, 0, 0, 1, 0Ch, 0, 0, 0, 0>
        public byte elemental;// Data           :     this+0x9, Member, Type: char, elemental <6, 10h, 0, 0, 1, 0Dh, 0, 0, 0, 0>
        public byte is_active;// Data           :     this+0xA, Member, Type: char, is_active <7, 10h, 0, 0, 1, 0Eh, 0, 0, 0, 0>
        public byte is_spell_act;// Data           :     this+0xB, Member, Type: char, is_spell_act <8, 10h, 0, 0, 1, 0Fh, 0, 0, 0, 0>
        public byte is_harmful;// Data           :     this+0xC, Member, Type: char, is_harmful <9, 10h, 0, 0, 1, 10h, 0, 0, 0, 0>
        public byte is_need_target;// Data           :     this+0xD, Member, Type: char, is_need_target <0Ah, 10h, 0, 0, 1, 11h, 0, 0, 0, 0>
        public byte is_corpse;// Data           :     this+0xE, Member, Type: char, is_corpse <0Bh, 10h, 0, 0, 1, 12h, 0, 0, 0, 0>
        public byte is_toggle;// Data           :     this+0xF, Member, Type: char, is_toggle <0Ch, 10h, 0, 0, 1, 13h, 0, 0, 0, 0>
        public byte cancel_type;// Data           :     this+0x10, Member, Type: char, cancel_type ? casting_type <0Dh, 3, 0, 0, 4, 18h, 0, 0, 0, 0>
        public byte cancel_level;// Data           :     this+0x11, Member, Type: char, cancel_level casting_level? <0Eh, 10h, 0, 0, 1, 14h, 0, 0, 0, 0>
        public int toggle_group;// Data           :     this+0x14, Member, Type: int, toggle_group <0Fh, 10h, 0, 0, 1, 15h, 0, 0, 0, 0>

        public int cast_range;// Data           :     this+0x18, Member, Type: int, cast_range
        public int valid_range;// Data           :     this+0x1C, Member, Type: int, valid_range
        public int cost_exp;// Data           :     this+0x20, Member, Type: int, cost_exp
        public int cost_exp_per_enhance;// Data           :     this+0x24, Member, Type: int, cost_exp_per_enhance
        public int cost_jp;// Data           :     this+0x28, Member, Type: int, cost_jp
        public int cost_jp_per_enhance;// Data           :     this+0x2C, Member, Type: int, cost_jp_per_enhance
        public int cost_hp;// Data           :     this+0x30, Member, Type: int, cost_hp
        public int cost_hp_per_skl;// Data           :     this+0x34, Member, Type: int, cost_hp_per_skl
        public int cost_mp;// Data           :     this+0x38, Member, Type: int, cost_mp
        public int cost_mp_per_skl;// Data           :     this+0x3C, Member, Type: int, cost_mp_per_skl
        public int cost_mp_per_enhance;// Data           :     this+0x40, Member, Type: int, cost_mp_per_enhance
        public float cost_hp_per;// Data           :     this+0x44, Member, Type: float, cost_hp_per
        public float cost_hp_per_skl_per;// Data           :     this+0x48, Member, Type: float, cost_hp_per_skl_per
        public float cost_mp_per;// Data           :     this+0x4C, Member, Type: float, cost_mp_per
        public float cost_mp_per_skl_per;// Data           :     this+0x50, Member, Type: float, cost_mp_per_skl_per
        public int cost_havoc;// Data           :     this+0x54, Member, Type: int, cost_havoc
        public int cost_havoc_per_skl;// Data           :     this+0x58, Member, Type: int, cost_havoc_per_skl
        public float cost_energy;// Data           :     this+0x5C, Member, Type: class c_fixed<10000>, cost_energy
// 
        public float cost_energy_per_skl;// Data           :     this+0x64, Member, Type: class c_fixed<10000>, cost_energy_per_skl
// 
        public int cost_item;// Data           :     this+0x6C, Member, Type: int, cost_item
        public int cost_item_count;// Data           :     this+0x70, Member, Type: int, cost_item_count
        public int cost_item_count_per_skl;// Data           :     this+0x74, Member, Type: int, cost_item_count_per_skl
        public int need_level;// Data           :     this+0x78, Member, Type: int, need_level
        public int need_hp;// Data           :     this+0x7C, Member, Type: int, need_hp
        public int need_mp;// Data           :     this+0x80, Member, Type: int, need_mp
        public int need_havoc;// Data           :     this+0x84, Member, Type: int, need_havoc
        public int need_havoc_burst;// Data           :     this+0x88, Member, Type: int, need_havoc_burst
        public int need_state_id;// Data           :     this+0x8C, Member, Type: int, need_state_id
        public byte need_state_level;// Data           :     this+0x90, Member, Type: unsigned char, need_state_level
        public byte need_state_exhaust;// Data           :     this+0x91, Member, Type: char, need_state_exhaust
        public byte vf_one_hand_sword;// Data           :     this+0x92, Member, Type: char, vf_one_hand_sword
        public byte vf_two_hand_sword;// Data           :     this+0x93, Member, Type: char, vf_two_hand_sword
        public byte vf_double_sword;// Data           :     this+0x94, Member, Type: char, vf_double_sword
        public byte vf_dagger;// Data           :     this+0x95, Member, Type: char, vf_dagger
        public byte vf_double_dagger;// Data           :     this+0x96, Member, Type: char, vf_double_dagger
        public byte vf_spear;// Data           :     this+0x97, Member, Type: char, vf_spear
        public byte vf_axe;// Data           :     this+0x98, Member, Type: char, vf_axe
        public byte vf_one_hand_axe;// Data           :     this+0x99, Member, Type: char, vf_one_hand_axe
        public byte vf_double_axe;// Data           :     this+0x9A, Member, Type: char, vf_double_axe
        public byte vf_one_hand_mace;// Data           :     this+0x9B, Member, Type: char, vf_one_hand_mace
        public byte vf_two_hand_mace;// Data           :     this+0x9C, Member, Type: char, vf_two_hand_mace
        public byte vf_lightbow;// Data           :     this+0x9D, Member, Type: char, vf_lightbow
        public byte vf_heavybow;// Data           :     this+0x9E, Member, Type: char, vf_heavybow
        public byte vf_crossbow;// Data           :     this+0x9F, Member, Type: char, vf_crossbow
        public byte vf_one_hand_staff;// Data           :     this+0xA0, Member, Type: char, vf_one_hand_staff
        public byte vf_two_hand_staff;// Data           :     this+0xA1, Member, Type: char, vf_two_hand_staff
        public byte vf_shield_only;// Data           :     this+0xA2, Member, Type: char, vf_shield_only
        public byte vf_is_not_need_weapon;// Data           :     this+0xA3, Member, Type: char, vf_is_not_need_weapon
        public uint delay_cast;// Data           :     this+0xA4, Member, Type: unsigned long, delay_cast
        public uint delay_cast_per_skl;// Data           :     this+0xA8, Member, Type: unsigned long, delay_cast_per_skl
        public float delay_cast_mod_per_enhance;// Data           :     this+0xAC, Member, Type: float, delay_cast_mod_per_enhance
        public uint delay_common;// Data           :     this+0xB0, Member, Type: unsigned long, delay_common
        public uint delay_cooltime;// Data           :     this+0xB4, Member, Type: unsigned long, delay_cooltime
        public float delay_cooltime_mod_per_enhance;// Data           :     this+0xB8, Member, Type: float, delay_cooltime_mod_per_enhance
        public int cool_time_group_id;// Data           :     this+0xBC, Member, Type: int, cool_time_group_id
        public float unkf1;
        public byte uf_self;// Data           :     this+0xC0, Member, Type: char, uf_self
        public byte uf_party;// Data           :     this+0xC1, Member, Type: char, uf_party
        public byte uf_guild;// Data           :     this+0xC2, Member, Type: char, uf_guild
        public byte uf_neutral;// Data           :     this+0xC3, Member, Type: char, uf_neutral
        public byte uf_purple;// Data           :     this+0xC4, Member, Type: char, uf_purple
        public byte uf_enemy;// Data           :     this+0xC5, Member, Type: char, uf_enemy
        public byte tf_avatar;// Data           :     this+0xC6, Member, Type: char, tf_avatar
        public byte tf_summon;// Data           :     this+0xC7, Member, Type: char, tf_summon
        public byte tf_monster;// Data           :     this+0xC8, Member, Type: char, tf_monster
        public short target;// Data           :     this+0xCA, Member, Type: short, target
        public short effect_type;// Data           :     this+0xCC, Member, Type: short, effect_type
        public int unkint1;
        public int unkint2;

        public int state_id;// Data           :     this+0xD0, Member, Type: int, state_id
        public int state_level_base;// Data           :     this+0xD4, Member, Type: int, state_level_base
        public float state_level_per_skl;// Data           :     this+0xD8, Member, Type: float, state_level_per_skl
        public float state_level_per_enhance;// Data           :     this+0xDC, Member, Type: float, state_level_per_enhance
        public uint state_second;// Data           :     this+0xE0, Member, Type: unsigned long, state_second
        public uint state_second_per_skl;// Data           :     this+0xE4, Member, Type: unsigned long, state_second_per_skl
        public uint state_second_per_enhance;// Data           :     this+0xE8, Member, Type: unsigned long, state_second_per_enhance
        public byte state_type;// Data           :     this+0xEC, Member, Type: char, state_type
        public int probability_on_hit;// Data           :     this+0xF0, Member, Type: int, probability_on_hit
        public int probability_inc_by_slv;// Data           :     this+0xF4, Member, Type: int, probability_inc_by_slv
        public short hit_bonus;// Data           :     this+0xF8, Member, Type: short, hit_bonus
        public short hit_bonus_enhance;// Data           :     this+0xFA, Member, Type: short, hit_bonus_enhace
        public short percentage;// Data           :     this+0xFC, Member, Type: short, percentage
        public float hate_mod;// Data           :     this+0x100, Member, Type: float, hate_mod
        public int hate_basic;// Data           :     this+0x104, Member, Type: int, hate_basic
        public float hate_slv;// Data           :     this+0x108, Member, Type: float, hate_slv
        public float hate_enhance;// Data           :     this+0x10C, Member, Type: float, hate_enhance
        public int critical_bonus;// Data           :     this+0x110, Member, Type: int, critical_bonus
        public int critical_bonus_per_skl;// Data           :     this+0x114, Member, Type: int, critical_bonus_per_skl
        public float[] m_var = new float[20];                           // 0x118
        public int[] m_need_jp = new int[50];                           // 0x1B8
        public byte effect_flag;// Data           :     this+0x280, Member, Type: char, effect_flag
        public byte is_projectile;// Data           :     this+0x281, Member, Type: char, is_projectile
        public float projectile_speed;// Data           :     this+0x284, Member, Type: float, projectile_speed
        public float projectile_acceleration;// Data           :     this+0x288, Member, Type: float, projectile_acceleration
// Function       :     public void SkillBase::SkillBase(const struct SkillBase &)
// Function       :     public void SkillBase::SkillBase()
// Function       :     public struct SkillBase & SkillBase::operator=(const struct SkillBase &)

    }
}
